package downstream

import (
	"context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/status"
	"inventory/api/bmember"
	"inventory/api/open"
	"inventory/internal/conf"
	"inventory/internal/constant"
	"inventory/pkg/ecode"
	"inventory/pkg/log"
	"inventory/pkg/network"
	"inventory/pkg/request_key"
	"strconv"
	"time"
)

func newOpenClient(ctx context.Context, addr string) (
	client open.OpenServiceClient, err error) {
	var conn *grpc.ClientConn
	conn, err = grpc.Dial(addr, grpc.WithInsecure(),
		grpc.WithUnaryInterceptor(network.ClientInterceptor(
			"bilin_open", time.Second*3, openErrorTranslator)))
	if err != nil {
		err = ecode.AppendMessage(constant.ErrRemoteAPIFailed, "授权管理服务地址无法建立有效连接, err=%s", err.Error())
		log.FromContext(ctx).Warnw(err.Error())
		return
	}
	client = open.NewOpenServiceClient(conn)
	return
}

func openErrorTranslator(err error) (errCode *ecode.ErrorCode) {
	rpcStatus := status.Convert(err)
	errCode = ecode.AppendMessage(
		constant.ErrRemoteAPIFailed, "授权管理服务调用失败，请稍后再试：%s", rpcStatus.Message())
	return
}

func (d *Downstream) GetWechatTemplates(ctx context.Context, appId string) (templateIds []string, err error) {
	if d.openClient == nil {
		if d.openClient, err = newOpenClient(
			ctx, conf.Conf.Downstream.OpenURL); err != nil {
			return
		}
	}
	var reply *open.GetWechatPubTemplatesReply
	clientCtx, cancel := request_key.NewOutGoingContext(ctx, time.Second*3)
	defer cancel()
	if reply, err = d.openClient.GetWechatPubTemplates(
		clientCtx, &open.GetWechatPubTemplatesRequest{
			Domain: "inventory",
			AppId:  appId,
		}); err != nil {
		return
	}
	templateIds = reply.TemplateIds
	return
}

func (d *Downstream) SendWechatTemplate(ctx context.Context, memberId string, msgType, page, data string) (err error) {
	if d.openClient == nil {
		if d.openClient, err = newOpenClient(
			ctx, conf.Conf.Downstream.OpenURL); err != nil {
			return
		}
	}
	var (
		memberReply *bmember.MemberOpenIdGetReply
		memberIntId int
	)
	if memberIntId, err = strconv.Atoi(memberId); err != nil {
		err = ecode.WithStack(err)
		return
	}
	if memberReply, err = d.GetMemberOpenId(ctx, int64(memberIntId), "mall_mina"); err != nil {
		return
	}
	clientCtx, cancel := request_key.NewOutGoingContext(ctx, time.Second*3)
	defer cancel()
	if _, err = d.openClient.SendWechatMiniPubMessage(clientCtx, &open.SendWechatMiniPubMessageRequest{
		AppId:   memberReply.AppId,
		OpenId:  memberReply.OpenId,
		MsgType: msgType,
		Page:    page,
		Data:    data,
	}); err != nil {
		return
	}
	return
}
